
#include "espsettings.h"
#include <WebSocketsServer.h>
#include "espwebsocket.h"
#include "map"

#define MAX_PRINTF_LEN 128
WebSocketsServer webSocket = WebSocketsServer(81);
std::map<String, CallbackFunction> attachMap;
uint8_t channel;
void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
{
    if (type == WStype_DISCONNECTED)
    {
        log_debug("[%u] Disconnected!\n", num);
    }
    else if (type == WStype_CONNECTED)
    {
        IPAddress ip = webSocket.remoteIP(num);
        log_debug("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
        channel = num;
        webSocket.sendTXT(num, "Connected");
    }
    else if (type == WStype_TEXT)
    {
        log_debug("[%u] get Text: %s\n", num, payload);
        DynamicJsonDocument jsonBuffer(400);
        DeserializationError error = deserializeJson(jsonBuffer, payload);

        // 检查是否是json格式或者格式是否异常
        if (error)
        {
            log_debug("deserialize failed");
        }
        else
        {
            String cmd = jsonBuffer["cmd"];
            if (cmd != NULL && attachMap[cmd] != NULL)
            {
                attachMap[cmd](jsonBuffer);
            }
        }
    }
}
void EspWebsocket::begin()
{
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);
}

void EspWebsocket::handle()
{
    webSocket.loop();
}
void EspWebsocket::print(String str)
{

    if (webSocket.clientIsConnected(channel))
    {
        webSocket.sendTXT(channel, str);
    }
}
void EspWebsocket::print(DynamicJsonDocument json)
{
    String jsonString;
    serializeJson(json, jsonString);
    print(jsonString);
}
void EspWebsocket::printf(const char *format, ...)
{
    va_list arg;
    va_start(arg, format);
    char *temp = new char[MAX_PRINTF_LEN];
    if (!temp)
    {
        va_end(arg);
        return;
    }
    char *buffer = temp;
    size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg);
    va_end(arg);

    if (len > (MAX_PRINTF_LEN - 1))
    {
        buffer = new char[len + 1];
        if (!buffer)
        {
            delete[] temp;
            return;
        }
        va_start(arg, format);
        vsnprintf(buffer, len + 1, format, arg);
        va_end(arg);
    }
    print(buffer);
    if (buffer != temp)
    {
        delete[] buffer;
    }
    delete[] temp;
}

void EspWebsocket::attach(String type, CallbackFunction callback)
{
    attachMap[type] = callback;
}